#pragma  once
#include "base/core/singleton.h"
#include "base/core/object_pool.h"
#include "base/core/point3.h"
#include "Creature.h"
#include "Player.h"
#include <map>
#include <list>

class Player;
class Monster;
class Npc;

class Drop;

class Object;

class Part;
class MovePart;
class SkillPart;
class BuffPart;
class PackagePart;
class MissionPart;
class ChatPart;
class DuplicatePart;
class AchievementPart;
class DeputyPart;
class PvpPart;

class TreasurePart;
class CollectPart;
class RunBusinessPart;
class TitlePart;
class WelfarePart;
class OperateLimitPart;
class HuoYueDuPart;
class HorsePart;
class GodPart;
class PandosPart;
class OperateWelfarePart;
class PayPart;
class AdventurePart;
struct MonsCreateParam;
struct DoubleListViewData;
struct DoubleNode;
//新加的生物类型统一在这个管理器进行分配
//游戏中统一的生物 部件分配器 该部件需要最后回收
//游戏所有生物指针的存放地方 其他模块最好只引用生物ID
class CreatureMgr : public IEventExecuteSink, public ManualSingleton<CreatureMgr>
{
	friend class ManualSingleton < CreatureMgr >;

protected:
	//游戏生物
	ObjectPool<Player> *m_pPlayerPool;
	ObjectPool<Monster>* m_pMonsterPool;
	ObjectPool<Npc>* m_pNpcPool;

	ObjectPool<Drop>* m_pDropPool;
	ObjectPool<Object> *m_pObjectPool;
	ObjectPool<CRebot> *m_pRebotPool;

	//游戏生物部件
	ObjectPool<MovePart>  *m_pMovePool;      //移动部件对象
	ObjectPool<SkillPart> *m_pSkillPool;      //技能部件对象
	ObjectPool<BuffPart> *m_pBuffPool; //buff部件对象
	ObjectPool<PackagePart> *m_pPackagePool;  //背包部件对象
	ObjectPool<MissionPart> *m_pMissionPoll;  //任务部件对象
	ObjectPool<ChatPart>	*m_pChatPoll;  //任务部件对象
	ObjectPool<DuplicatePart>	*m_pDuplicatePool;  //副本部件对象
	ObjectPool<AchievementPart>	*m_pAchievementPool;  //成就部件对象
	ObjectPool<DeputyPart>	*m_pDeputyPool;  //副业部件对象
	ObjectPool<PvpPart>			*m_pPvpPool;  //PVP部件对象

	ObjectPool<TreasurePart>  *m_pTreasurePool;	//挖宝部件对象
	ObjectPool<CollectPart> *m_pCollectPool;	//采集部件对象
	ObjectPool<RunBusinessPart>* m_pRunBusinessPool; //跑商部件
	ObjectPool<TitlePart> * m_pTitlePartPool;		//称号部件
	ObjectPool<OperateWelfarePart> *m_pWelfarePartPool;		//福利部件
	ObjectPool<OperateLimitPart> *m_pOperateLimitPartPool;		//统计部件
	ObjectPool<HuoYueDuPart> *m_huoYueDuPartPool;	//活跃度
	ObjectPool<HorsePart> *m_pHorsePartPool;	//坐骑部件
	ObjectPool<GodPart> *m_pGodPartPool;	//坐骑部件
	ObjectPool<PandosPart> *m_pPandosPool;	//星盘
	ObjectPool<PayPart> *m_pPayPool;	//星盘
	ObjectPool<AdventurePart> *m_pAdventurePool;	//奇遇	
	ObjectPool<DoubleListViewData> *m_pDoubleListPool;	//视野结构
	ObjectPool<DoubleNode> *m_pDoubleNodePool;	//视野结构
	CharIDType	m_creatureId;  //这里是记录序号，拼凑在nextid函数中
public:
	CreatureMgr();
	virtual ~CreatureMgr();
	//////////////////////////////////////////////////////////////////////////
	virtual void OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen);
public:
	bool Init();
	bool UnInit();
	void Update(uint64_t tick);
	void DebugLog();
	DoubleListViewData * GetDoublelistView();
	DoubleNode   * GetDoubleNode();
	void RecycleDoubleListView(DoubleListViewData * pDoubleList);
	void RecycleDoubleNode(DoubleNode   * pDoubleNode);
public:
	Creature* MallocCreature(CreatureType type);
	void RecyleCreature(Creature* pCreature);
	//第50位为1，后49位用于序号ID
	CharIDType NextId(){ return ((uint64_t)1 << 49) + (++m_creatureId); };

	Part* CreatePart(uint32_t partType, Creature *pCreature, CharacterDBInfo *playerInfo = nullptr);
	void RecylePart(Part *pPart);

public: //操作玩家生物接口
	Player* GetPlayer(CharIDType PlayerId);
	//获取非场景玩家指针
	Player* GetNoScenePlayer(CharIDType PlayerId);
	void RecylePlayer(CharIDType playerId);
	Player* CreatePlayer(CharLoginInfo* pLoginInfo, CharacterDBInfo &playerInfo, bool change);
	int  GetPlayerCount();
	bool SaveAllPlayer();
	//每日更新
	bool DailyUpdate(uint64_t unixSec);
	//每周刷新
	bool WeekUpdate(uint64_t unixSec);
	//每日零点更新
	bool DailyZeroUpdate(uint64_t unixSec);
	//每周零点刷新
	bool WeekZeroUpdate(uint64_t unixSec);
	//更新活动状态
	bool UpdateActivityState(uint32_t actId);

	void GetGateClientIds(MAP_UINT32_LST_UINT32& gateClientsMap, SET_UINT64& charIds);

	void GetGateClientId(CharIDType cid, uint32_t& gateId, uint32_t& clientId);

	AccountGameState GetPlayerAccountState(CharIDType cid);

	void ClearAllPlayerActiveAnswerData();

public://怪物接口
	Monster* CreateMonster(uint32_t monsterId, uint32_t sceneId, Point3<float> bornPos, MonsCreateParam &createParam, Point3<float> dir = Point3<float>(0, 0, 1), int32_t monsIdx = -1, MonsterExtendInfo * pExtend = NULL, CharIDType createrID = 0, uint32_t monsterGroup = 0);
	void RecyleMonster(Monster* pmonster);
	Monster* GetMonster(CharIDType monsterCid);
	void SetAIEnable(bool use);

public: //NPC接口  npcIdx:对应地编中NPC所在的索引，动态刷出来索引为默认值 从0开始，默认为-1，
	Npc* CreateNpc(uint32_t npcId, uint32_t sceneId, Point3<float>& bornPos,int32_t npcIdx = -1);
	void RecyleNpc(Npc* pNpc);
	Npc* GetNpc(CharIDType npcCid);
	Npc* GetNpc(uint32_t npcCnfigID);
	std::list<Npc*>* GetNpcTeam(uint32_t sceneId, uint32_t teamId);
	std::list<Monster*>* GetMonsterGroup(uint32_t sceneId, uint32_t groupId);
	void NpcTeamAddNpc(uint32_t sceneId, uint32_t teamId, Npc* pNpc, uint32_t teamSort);
	void NpcTeamDelNpc(uint32_t sceneId, uint32_t teamId, Npc* pNpc);
	void MonsterGroupAddMonster(uint32_t sceneId, uint32_t groupId, Monster* pMonster);
	void MonsterGroupDelMonster(uint32_t sceneId, uint32_t groupId, Monster* pMonster);
	void NpcTeamSyncHate(uint32_t sceneId, uint32_t teamId, Npc* pNpc, CharIDType targetCid, uint32_t hateValue);
	bool IsTeamLeader(uint32_t sceneId, uint32_t teamId, Npc* pNpc);
	Npc* FindTeamFollower(uint32_t sceneId, uint32_t teamId, Npc* pNpc);
	Npc* FindTeamLeader(uint32_t sceneId, uint32_t teamId);
public://采集物接口
	Object*	 CreateObject(uint32_t nObjectId, uint32_t nSceneId, Point3<float>& bornPos, int32_t posIdx);
	void RecycleObject(Object* pObject);

public: //操作游戏中所有生物接口
	Creature* GetCreature(CharIDType cid);
	Creature* GetNoSceneCreature(CharIDType cid);
	void MasterEneterScene(Creature* pMaster, uint32_t sceneId, Point3<float>& enterPos);
	void MasterLeaveScene(Creature* pMaster);
public:
	//创建掉落 fromWho : 从谁身上掉落的，目前只用在杀戮之石掉落的时候,initProtect:掉落初始保护时间
	Drop* CreateDropEx(CItemBase *pItem, uint32_t nGold, uint32_t nSceneID, Point3<float> &pos, int8_t byDropType, SET_UINT64 &setTypeVal, int32_t initProtect, SDropSourcePram &sourceParam, uint64_t fromWho = 0);
	bool RecycleDrop(Drop *pDrop);
	Drop *GetDrop(CharIDType dropCid);

public://机器人
	CRebot* GetRebot(CharIDType rebotCid);
	CRebot * CreateRebot(uint32_t rebotID);
	CRebot * CreateRebot(const CharacterMirrorData & stData);
	void RecyleRebot(CRebot* pRebot);
private:
	//目标逻辑节点 生物切换逻辑节点
	void OnCreatureChangeLogic(CreatureTransParam &param);
	//源逻辑节点 生物切换逻辑节点校验结果
	void OnCreatureChangeLogicCheckRes(TransCheckResEvent *pCheckEvent);

public:	//将要回收的生物加入到待回收队列
	void WaitDestory(CharIDType creatureID);
	void WaitDestory(Creature *pCreature);
	//立即销毁
	void Destory(CharIDType creatureID);
	void Destory(Creature *pCreature);

public:
	MAP_Player	 m_mapPlayer;				// 玩家数据表
	//MAP_Player	 m_destoryPlayer;		// 待回收内存的玩家列表
	KList m_onlineList;						// 正常在线玩家列表

	MAP_Creature m_allCreature;				// 所有生物指针
	MAP_Creature m_destoryCreature;			// 准备回收的生物指针
	uint64_t     m_debugStartTime;			//记录开始打印时间
public:
	std::map<uint32_t, std::map<uint32_t, std::list<Npc*>>> m_npcTeam;
	std::map<uint32_t, std::map<uint32_t, std::list<Monster*>>> m_monsterGroup;
};

#define g_MakeCreatureMgr() (CreatureMgr::Instance())
#define g_GetCreatureMgr()  (CreatureMgr::GetInstance())
#define g_DelCreatureMgr()  (CreatureMgr::Destroy())
